# chanrelay.tcl 2.2
#
# A way to link your channels
# 
# Author: CrazyCat <crazycat@c-p-f.org>
# http://www.eggdrop.fr
# irc.zeolia.net #eggdrop

## DESCRIPTION ##
#
# This TCL is a complete relay script wich works with botnet.
# All you have to do is to include this tcl in all the eggdrop who
# are concerned by it.
#
# You can use it as a spy or a full duplex communication tool.
#
# It don't mind if the eggdrops are on the same server or not,
# it just mind about the channels and the handle of each eggdrop.

## EVOLUTION ##
#
# 2.2 : Added !who channel command
#       Private messaging by doing /msg <botnick> say user@network your message
#       

## TODO ##
#
# Reorganise configuration (eggdrops / chans / networks)
# Use a namespace
# Add inter-networks commands

## CONFIGURATION ##

# Fill the values as you want but don't forget to keep the same order between each array.
#set eggdrops {"CrazyEgg" "Excalibur" "CC_Egg" "LangoEgg" "Gertrude"}
#set chans {"#eggdrop" "#eggdrop" "#eggdrop.fr" "#eggdrop" "#eggdrop"}
#set networks {"Epiknet" "Zeolia" "Undernet" "Langochat" "Partage"}
set eggdrops {"CrazyEgg" "Excalibur" "CC_Egg"}
set chans {"#eggdrop" "#eggdrop" "#eggdrop.fr"}
set networks {"Epiknet" "Zeolia" "Undernet"}
# Remember that all is case sensitive, so don't write DuMmY if your eggdrop is named dummy :)

# Do you want to use bold (1), underline (2) or nothing (0) to higtlight nicknames ?
set high "0"

# Do yo want to indicate from wich network comes the message (y/n)?
set snet "y"

# Do you want the bot transmit actions from the channel (y/n)?
set transmit "y"; # default value is yes

# Do you want the bot recept actions (y/n)?
set receive "y"; # default value is yes

# transmission configuration
set trans_pub "y"; # transmit the pub
set trans_act "y"; # transmit the actions (/me)
set trans_nick "y"; # transmit the nick changement
set trans_join "y"; # transmit the join
set trans_part "y"; # transmit the part
set trans_quit "y"; # transmit the quit
set trans_topic "y"; # transmit the topic changements
set trans_kick "y"; # transmit the kicks
set trans_mode "n"; #transmit the mode changements
set trans_who "y"; # transmit the who list

# reception configuration
set recv_pub "y"; # recept the pub
set recv_act "y"; # recept the actions (/me)
set recv_nick "y"; # recept the nick changement
set recv_join "y"; # recept the join
set recv_part "y"; # recept the part
set recv_quit "y"; # recept the quit
set recv_topic "y"; # recept the topic changements
set recv_kick "y"; # recept the kicks
set recv_mode "n"; # recept the mode changements
set recv_who "y"; # recept the who list

############################################################
#
# The TCL begins here, if you don't know what to do, don't do anything :)
#
############################################################

bind msg o|o "rc.status" help:status
bind msg - "rc.help" help:cmds

if { $high == "1" } {
	set hlnick "\002"
} elseif { $high == "2" } {
	set hlnick "\037"
} else {
	set hlnick ""
}

bind msg o|o "rc.light" set:light
bind msg o|o "rc.net" set:snet

if { $transmit == "y" } {
	bind msg o|o "trans" set:trans
	if { $trans_pub == "y" } { bind pubm - * trans_pub }
	if { $trans_act == "y" } { bind ctcp - "ACTION" trans_act }
	if { $trans_nick == "y" } { bind nick - * trans_nick }
	if { $trans_join == "y" } { bind join - * trans_join }
	if { $trans_part == "y" } { bind part - * trans_part }
	if { $trans_quit == "y" } { bind sign - * trans_quit }
	if { $trans_topic == "y" } { bind topc - * trans_topic }
	if { $trans_kick == "y" } { bind kick - * trans_kick }
    if { $trans_mode == "y" } { bind mode - * trans_mode }
    if { $trans_who == "y" } { bind pub - "!who" trans_who }
}

if { $receive =="y" } {
	bind msg o|o "recv" set:recv
	if { $recv_pub == "y" } { bind bot - ">pub" recv_pub }
	if { $recv_act == "y" } { bind bot - ">act" recv_act }
	if { $recv_nick == "y" } { bind bot - ">nick" recv_nick }
	if { $recv_join == "y" } { bind bot - ">join" recv_join }
	if { $recv_part == "y" } { bind bot - ">part" recv_part }
	if { $recv_quit == "y" } { bind bot - ">quit" recv_quit }
	if { $recv_topic == "y" } { bind bot - ">topic" recv_topic }
	if { $recv_kick == "y" } { bind bot - ">kick" recv_kick }
    if { $recv_mode == "y" } { bind bot - ">mode" recv_mode }
    if { $recv_who == "y" } {
	    bind bot - ">who" recv_who
	    bind bot - ">wholist" recv_wholist
	}
}	

# proc setting the type of highlight
proc set:light {nick host handle arg } {
	if { $arg == "bo" } {
		set ::hlnick "\002"
	} elseif { $arg == "un" } {
		set ::hlnick "\037"
	} elseif { $arg == "off" } {
		set ::hlnick ""
	} else { putquick "NOTICE $nick :you must chose \002(bo)\002ld , \037(un)\037derline or (off)" }
}

proc set:snet {nick host handle arg } {
	if { $arg == "yes" } {
		set ::snet "y"
	} elseif { $arg == "no" } {
		set ::snet "n"
	} else { putquick "NOTICE $nick :you must chose yes or no" }
}
# proc setting of transmission by msg
proc set:trans { nick host handle arg } {
	if { $::transmit == "y" } {
		if { $arg == "" } {
			putquick "NOTICE $nick :you'd better try /msg $::botnick trans help"
		}
		if { [lindex [split $arg] 0] == "help" } {
			putquick "NOTICE $nick :usage is /msg $::botnick trans <value> on|off"
			putquick "NOTICE $nick :with <value> = pub, act, nick, join, part, quit, topic, kick, mode, who"
			return 0
		} else {
			set proc_change "trans_[lindex [split $arg] 0]"
			switch [lindex [split $arg] 0] {
				"pub" { set type pubm }
				"act" { set type ctcp }
				"nick" { set type nick }
				"join" { set type join }
				"part" { set type part }
				"quit" { set type sign }
				"topic" { set type topc }
				"kick" { set type kick }
				"mode" { set type mode }
				"who" { set type who }
			}
			if { [lindex [split $arg] 1] == "on" } {
				bind $type - * $proc_change
			} elseif { [lindex [split $arg] 1] == "off" } {
				unbind $type - * $proc_change
			} else {
				putquick "NOTICE $nick :[lindex [split $arg] 1] is not a correct value, choose \002on\002 or \002off\002"
			}
		}
	} else {
		putquick "NOTICE $nick :transmission is not activated, you can't change anything"
	}
}

# proc setting of reception by msg
proc set:recv { nick host handle arg } {
	if { $::receive == "y" } {
		if { $arg == "" } {
			putquick "NOTICE $nick :you'd better try /msg $::botnick recv help"
		}
		if { [lindex [split $arg] 0] == "help" } {
			putquick "NOTICE $nick :usage is /msg $::botnick recv <value> on|off"
			putquick "NOTICE $nick :with <value> = pubm, act, nick, join, part, quit, topic, kick, mode, who"
			return 0
		} else {
			set change ">[lindex [split $arg] 0]"
			set proc_change "recv_[lindex [split $arg] 0]"
			if { [lindex [split $arg] 1] == "on" } {
				bind  bot - $change $proc_change
			} elseif { [lindex [split $arg] 1] == "off" } {
				unbind bot - $change $proc_change
			} else {
				putquick "NOTICE $nick :[lindex [split $arg] 1] is not a correct value, choose \002on\002 or \002off\002"
			}
		}
	} else {
		putquick "NOTICE $nick :reception is not activated, you can't change anything"
	}
}

####################################################
#
# Transmission
#

# proc used by all others for transmission
proc trans_bot { usercmd chan usernick text } {
	set transmsg [concat $usercmd $usernick $text]
	set me [lsearch $::eggdrops $::botnick]
	if {$chan == [lindex $::chans $me]} {
		putallbots $transmsg
	} else {
		return 0
	}
}

# proc transmission of pub (trans_pubm = y)
proc trans_pub {nick uhost hand chan text} {
	if { [string tolower [lindex [split $text] 0]] == "!who" } { return 0; }
	trans_bot ">pub" $chan $nick [join [split $text]]
}

# proc transmission of action (trans_act = y)
proc trans_act {nick uhost hand chan key text} {
	set arg [concat $key $text]
	trans_bot ">act" $chan $nick $arg
}

# proc transmission of nick changement
proc trans_nick {nick uhost hand chan newnick} {
	trans_bot ">nick" $chan $nick $newnick
}

# proc transmission of join
proc trans_join {nick uhost hand chan} {
	trans_bot ">join" $chan $chan $nick
}

# proc transmission of part
proc trans_part {nick uhost hand chan text} {
	set arg [concat $chan $text]
	trans_bot ">part" $chan $nick $arg
}

# proc transmission of quit
proc trans_quit {nick host hand chan text} {
	trans_bot ">quit" $chan $nick $text
}

# proc transmission of topic changement
proc trans_topic {nick uhost hand chan topic} {
	set arg [concat $chan $topic]
	trans_bot ">topic" $chan $nick $arg
}

# proc transmission of kick
proc trans_kick {nick uhost hand chan victim reason} {
	set arg [concat $victim $chan $reason]
	trans_bot ">kick" $chan $nick $arg
}

# proc transmission of mode changement
proc trans_mode {nick uhost hand chan mc {victim ""}} {
	if {$victim != ""} {append mc " $victim" }
	set text [concat $nick $chan $mc]
	trans_bot ">mode" $chan $nick $text
}

# proc transmission of "who command"
proc trans_who {nick uhost handle chan args} {
    trans_bot ">who" $chan $nick ""
}

####################################################
#
# Reception
#

# proc reception of pub
proc recv_pub {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 0] $him]
		putquick "PRIVMSG $recvchan :$speaker> [join [lrange $argl 1 end]]"
    }
	return 0
}

# proc reception of action
proc recv_act {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 0] $him]
		putquick "PRIVMSG $recvchan :* $speaker [join [lrange $argl 2 end]]"
	}
	return 0
}

# proc reception of nick changement
proc recv_nick {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 0] $him]
		putquick "PRIVMSG $recvchan :*** $speaker is now known as [join [lrange $argl 1 end]]"
	}
	return 0
}

# proc reception of join
proc recv_join {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 1] $him]
		putquick "PRIVMSG $recvchan :--> $speaker has joined channel [lindex $argl 0]"
	}
	return 0
}

# proc reception of part
proc recv_part {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 0] $him]
		putquick "PRIVMSG $recvchan :<-- $speaker has left channel [lindex $argl 1] ([join [lrange $argl 2 end]])"
	}
	return 0
}

# proc reception of quit
proc recv_quit {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 0] $him]
		putquick "PRIVMSG $recvchan :-//- $speaker has quit ([join [lrange $argl 1 end]])"
	}
	return 0
}

# proc reception of topic changement
proc recv_topic {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 0] $him]
		putquick "PRIVMSG $recvchan :*** $speaker changes topic of [lindex $argl 1] to '[join [lrange $argl 2 end]]'"
	}
	return 0
}

# proc reception of kick
proc recv_kick {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 1] $him]
		putquick "PRIVMSG $recvchan :*** $speaker has been kicked from [lindex $argl 2] by [lindex $argl 0]: [join [lrange $argl 3 end]]"
	}
	return 0
}

# proc reception of mode changement
proc recv_mode {frm_bot command arg} {
	if {[set him [lsearch $::eggdrops $frm_bot]] >= 0} {
		set argl [split $arg]
		set me [lsearch $::eggdrops $::botnick]
		set recvchan [lindex $::chans $me]
		set speaker [make_user [lindex $argl 1] $him]
		putquick "PRIVMSG $recvchan :*** $speaker set mode [join [lrange $argl 2 end]]"
	}
	return 0
}

proc recv_who {frm_bot command arg} {
	set nick $arg
	set me [lsearch $::eggdrops $::botnick]
	set ulist ""
	set cusr 0
	foreach user [chanlist [lindex $::chans $me]] {
		if { $user == $::botnick } { continue; }
		if { [isop $user [lindex $::chans $me]] == 1 } {
			set st "@"
		} elseif { [ishalfop $user [lindex $::chans $me]] == 1 } {
			set st "%"
		} elseif { [isvoice $user [lindex $::chans $me]] == 1 } {
			set st "%"
		} else {
			set st ""
		}
		incr cusr 1
		append ulist " $st$user"
		if { $cusr == 5 } {
			trans_bot ">wholist" [lindex $::chans $me] $nick $ulist
			set ulist ""
			set cusr 0
		}
	}
	if { $ulist != "" } {
    	trans_bot ">wholist" [lindex $::chans $me] $nick $ulist
	}
}

proc recv_wholist {frm_bot command arg} {
	set nick [join [lindex [split $arg] 0]]
	set him [lsearch $::eggdrops $frm_bot]
	set me [lsearch $::eggdrops $::botnick]
	set speaker [make_user $frm_bot $him]
	putserv "NOTICE $nick :$speaker [join [lrange [split $arg] 1 end]]"
}

proc make_user { unick thenb } {
	if { $::snet == "y" } {
			set speaker [concat "$::hlnick\($unick@[lindex $::networks $thenb]\)$::hlnick"]
		} else {
			set speaker $hlnick$unick$hlnick
		}
	return $speaker
}

######################################
# proc for private messaging
#

bind msg - "say" prv:say_send
proc prv:say_send {nick uhost handle text} {
	set dest [join [lindex [split $text] 0]]
	set msg [join [lrange [split $text] 1 end]]
	set vict [join [lindex [split $dest @] 0]]
	set net [join [lindex [split $dest @] 1]]
	if { $vict == "" || $net == "" } {
		putserv "PRIVMSG $nick :Use \002!say user@network your message to user\002";
		return 0
	}
	set him [lsearch -nocase $::networks $net]
	if { $him == -1 } {
		putserv "PRIVMSG $nick :\002$net\002 is not a network I know";
		return 0
	}
	if { [string length $msg] == 0 } {
		putserv "PRIVMSG $nick :Did you forget what you want to say ?";
		return 0
	}
	set me [lsearch $::eggdrops $::botnick]
	putbot [lindex $::eggdrops $him] ">pvmsg $vict $nick@[lindex $::networks $me] $msg"
}

bind bot - ">pvmsg" prv:say_get
proc prv:say_get {frm_bot command arg} {
	set dest [join [lindex [split $arg] 0]]
	set from [join [lindex [split $arg] 1]]
	set msg [join [lrange [split $arg] 2 end]]
	set me [lsearch $::eggdrops $::botnick]
	if { [onchan $dest [lindex $::chans $me]] == 1 } {
		putserv "PRIVMSG $dest :$from: $msg"
	}
}

######################################
# proc for helping
#

# proc status
proc help:status { nick host handle arg } {
	putquick "PRIVMSG $nick :\002 Global status\002"
	putquick "PRIVMSG $nick :\037type\037   -- | trans -|- recept |"
	putquick "PRIVMSG $nick :global -- | -- $::transmit -- | -- $::receive -- |"
	putquick "PRIVMSG $nick :pub    -- | -- $::trans_pub -- | -- $::recv_pub -- |"
	putquick "PRIVMSG $nick :act    -- | -- $::trans_act -- | -- $::recv_act -- |"
	putquick "PRIVMSG $nick :nick   -- | -- $::trans_nick -- | -- $::recv_nick -- |"
	putquick "PRIVMSG $nick :join   -- | -- $::trans_join -- | -- $::recv_join -- |"
	putquick "PRIVMSG $nick :part   -- | -- $::trans_part -- | -- $::recv_part -- |"
	putquick "PRIVMSG $nick :quit   -- | -- $::trans_quit -- | -- $::recv_quit -- |"
	putquick "PRIVMSG $nick :topic  -- | -- $::trans_topic -- | -- $::recv_topic -- |"
	putquick "PRIVMSG $nick :kick   -- | -- $::trans_kick -- | -- $::recv_kick -- |"
	putquick "PRIVMSG $nick :mode   -- | -- $::trans_mode -- | -- $::recv_mode -- |"
	putquick "PRIVMSG $nick :who   -- | -- $::trans_who -- | -- $::recv_who -- |"
	putquick "PRIVMSG $nick :nicks appears as $::hlnick$nick$::hlnick"
	putquick "PRIVMSG $nick :\002 END of STATUS"
}

# proc help
proc help:cmds { nick host handle arg } {
	putquick "NOTICE $nick :/msg $::botnick trans <type> on|off to change the transmissions"
	putquick "NOTICE $nick :/msg $::botnick recv <type> on|off ti change the receptions"
	putquick "NOTICE $nick :/msg $::botnick rc.status to see my actual status"
	putquick "NOTICE $nick :/msg $::botnick rc.help for this help"
	putquick "NOTICE $nick :/msg $::botnick rc.light <bo|un|off> to bold, underline or no higlight"
	putquick "NOTICE $nick :/msg $::botnick rc.net <yes|no> to show the network"
}

# End !
putlog "CHANRELAY 2.2 by \002CrazyCat\002 loaded - http://www.eggdrop.fr"
